package com.vanke.devops.domain.domain.endpoints;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.vanke.core.util.CollectionUtil;
import com.vanke.core.util.JsonUtil;
import com.vanke.devops.dal.model.Endpoints;
import com.vanke.devops.domain.domain.endpoints.dto.EndpointsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 陈景阳
 * @since 2018/4/10
 */
@Slf4j
@ServerEndpoint("/endpoints")
@Component
public class EndpointsWebSocket {

    private static Set<EndpointsWebSocket> endpointsWebSockets = Sets.newCopyOnWriteArraySet();

    @Autowired
    private IEndpointsService endpointsService;

    private List<Endpoints> endpoints;

    @PostConstruct
    public void getEndpoints(){
        endpoints = endpointsService.getAll();
    }

    @Scheduled(fixedDelay = 20 * 1000)
    public void getNode(){
        if(CollectionUtil.isEmpty(endpointsWebSockets)){
            return;
        }

        for(Endpoints endpoint :endpoints){
            try {
                //TODO 优化
                EndpointsDTO dto = endpointsService.getNodeInfo(endpoint.getId());
                for(EndpointsWebSocket endpointsWebSocket : endpointsWebSockets){
                    endpointsWebSocket.sendMessage(JsonUtil.toJson(dto));
                }
            }catch (Exception e){
                log.error("get node error : {}",e.getMessage());
            }
        }
    }

    private Session session;

    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        log.info("on open , session : {}",session.getId());

        endpointsWebSockets.add(this);
    }

    @OnClose
    public void onClose(Session session){
        log.info("on close , session : {}",session.getId());
        endpointsWebSockets.remove(this);
    }

    private void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (!super.equals(o)) {
            return false;
        }
        EndpointsWebSocket that = (EndpointsWebSocket) o;
        return Objects.equals(endpointsService, that.endpointsService) &&
                Objects.equals(endpoints, that.endpoints) &&
                Objects.equals(session, that.session);
    }

    @Override
    public int hashCode() {

        return Objects.hash(super.hashCode(), endpointsService, endpoints, session);
    }
}
